﻿using Project2.多线程;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Project2.多线程
{
    public abstract class BaseCounter
    {
        public abstract void Add();

        public abstract void Del();

        public abstract long GetRes();
    }

    /// <summary>
    /// 线程不安全的计数器
    /// </summary>
    public class Counter : BaseCounter
    {
        private long counter;

        public override void Add()
        {
            counter++;
        }

        public override void Del()
        {
            counter--;
        }

        public override long GetRes()
        {
            return counter;
        }
    }

    /// <summary>
    /// 线程安全的计数器
    /// </summary>
    public class ThreadSafeCounter : BaseCounter
    {
        /// <summary>
        /// 线程锁对象
        /// </summary>
        private readonly object lockObj = new object();

        private long counter;

        public override void Add()
        {
            lock (lockObj)  //锁定一个对象,需要访问该对象的所有其他线程就会处于阻塞状态，并等待直到该对象接触锁定
            {
                counter++;
            }
        }

        public override void Del()
        {
            lock (lockObj)
            {
                counter--;
            }
        }

        public override long GetRes()
        {
            return counter;
        }
    }

    internal class 测试线程锁
    {
        /// <summary>
        /// 线程函数 测试计数器
        /// </summary>
        /// <param name="c"></param>
        private static void TestCounter(BaseCounter c)
        {
            for (int i = 0; i < 10000000; i++)
            {
                c.Add();
                c.Del();
            }
        }

        private static void Main测试线程锁()
        {
            //测试不安全的计数器
            //创建3个线程同时对计数器进行加减
            Counter c = new Counter();
            Thread t1 = new Thread(() => { TestCounter(c); });
            Thread t2 = new Thread(() => { TestCounter(c); });
            Thread t3 = new Thread(() => { TestCounter(c); });
            t1.Start();
            t2.Start();
            t3.Start();
            t1.Join();
            t2.Join();
            t3.Join();
            //等三个线程都执行完之后打印结果 看是否为0
            Console.WriteLine("count =   " + c.GetRes());

            //测试线程安全的计数器
            //创建3个线程同时对计数器进行加减
            ThreadSafeCounter c1 = new ThreadSafeCounter();
            t1 = new Thread(() => { TestCounter(c1); });
            t2 = new Thread(() => { TestCounter(c1); });
            t3 = new Thread(() => { TestCounter(c1); });
            t1.Start();
            t2.Start();
            t3.Start();
            t1.Join();
            t2.Join();
            t3.Join();
            //等三个线程都执行完之后打印结果 看是否为0
            Console.WriteLine("count =   " + c1.GetRes());
        }
    }
}